"""
Logging Configuration
日志配置 - 结构化日志，无外部依赖
"""

import logging
import logging.config
import structlog
from datetime import datetime
from pathlib import Path

from .config import settings


def setup_logging():
    """设置日志配置"""

    # 创建日志目录
    log_dir = Path(settings.logging.file_path).parent
    log_dir.mkdir(parents=True, exist_ok=True)

    # 标准日志配置
    logging_config = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": {
            "standard": {
                "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
                "datefmt": "%Y-%m-%d %H:%M:%S",
            },
            "detailed": {
                "format": (
                    "%(asctime)s [%(levelname)s] %(name)s:%(lineno)d: %(message)s"
                ),
                "datefmt": "%Y-%m-%d %H:%M:%S",
            },
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "level": settings.logging.level,
                "formatter": "standard",
                "stream": "ext://sys.stdout",
            },
            "file": {
                "class": "logging.handlers.RotatingFileHandler",
                "level": settings.logging.level,
                "formatter": "detailed",
                "filename": settings.logging.file_path,
                "maxBytes": settings.logging.max_size_mb * 1024 * 1024,
                "backupCount": settings.logging.backup_count,
                "encoding": "utf8",
            },
        },
        "loggers": {
            "": {  # root logger
                "handlers": ["console", "file"],
                "level": settings.logging.level,
                "propagate": False,
            },
            "uvicorn": {
                "handlers": ["console", "file"],
                "level": settings.logging.level,
                "propagate": False,
            },
            "sqlalchemy": {
                "handlers": ["file"],
                "level": "WARNING",  # 减少SQL日志噪音
                "propagate": False,
            },
        },
    }

    # 应用标准日志配置
    logging.config.dictConfig(logging_config)

    # 配置structlog
    if settings.logging.enable_structured_logging:
        structlog.configure(
            processors=[
                structlog.stdlib.filter_by_level,
                structlog.stdlib.add_logger_name,
                structlog.stdlib.add_log_level,
                structlog.stdlib.PositionalArgumentsFormatter(),
                structlog.processors.TimeStamper(fmt="iso"),
                structlog.processors.StackInfoRenderer(),
                structlog.processors.format_exc_info,
                structlog.processors.UnicodeDecoder(),
                structlog.processors.JSONRenderer(),
            ],
            context_class=dict,
            logger_factory=structlog.stdlib.LoggerFactory(),
            wrapper_class=structlog.stdlib.BoundLogger,
            cache_logger_on_first_use=True,
        )
    else:
        structlog.configure(
            processors=[
                structlog.stdlib.filter_by_level,
                structlog.stdlib.add_logger_name,
                structlog.stdlib.add_log_level,
                structlog.stdlib.PositionalArgumentsFormatter(),
                structlog.processors.TimeStamper(fmt="iso"),
                structlog.processors.StackInfoRenderer(),
                structlog.processors.format_exc_info,
                structlog.processors.UnicodeDecoder(),
                structlog.dev.ConsoleRenderer(),
            ],
            context_class=dict,
            logger_factory=structlog.stdlib.LoggerFactory(),
            wrapper_class=structlog.stdlib.BoundLogger,
            cache_logger_on_first_use=True,
        )


class RequestLogger:
    """请求日志中间件"""

    def __init__(self):
        self.logger = structlog.get_logger("request")

    async def __call__(self, request, call_next):
        """记录请求日志"""
        start_time = datetime.now()

        # 记录请求开始
        self.logger.info(
            "请求开始",
            method=request.method,
            url=str(request.url),
            client_ip=request.client.host if request.client else "unknown",
            user_agent=request.headers.get("user-agent", "unknown"),
        )

        # 处理请求
        response = await call_next(request)

        # 计算处理时间
        process_time = (datetime.now() - start_time).total_seconds()

        # 记录请求完成
        self.logger.info(
            "请求完成",
            method=request.method,
            url=str(request.url),
            status_code=response.status_code,
            process_time=process_time,
            client_ip=request.client.host if request.client else "unknown",
        )

        # 添加处理时间头部
        response.headers["X-Process-Time"] = str(process_time)

        return response


class ErrorLogger:
    """错误日志处理器"""

    def __init__(self):
        self.logger = structlog.get_logger("error")

    def log_error(self, error: Exception, context: dict = None):
        """记录错误日志"""
        error_info = {
            "error_type": type(error).__name__,
            "error_message": str(error),
            "context": context or {},
        }

        # 添加堆栈跟踪
        import traceback

        error_info["stack_trace"] = traceback.format_exc()

        self.logger.error("应用错误", **error_info)

    def log_warning(self, message: str, context: dict = None):
        """记录警告日志"""
        self.logger.warning(message, context=context or {})

    def log_info(self, message: str, context: dict = None):
        """记录信息日志"""
        self.logger.info(message, context=context or {})


# 全局错误日志实例
error_logger = ErrorLogger()

# 导出日志工具
__all__ = ["setup_logging", "RequestLogger", "ErrorLogger", "error_logger"]
